home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gekikoh Dennoh Club 2
/
Gekikoh Dennoh Club Vol. 2 (Japan).7z
/
Gekikoh Dennoh Club Vol. 2 (Japan) (Track 01).bin
/
tools
/
post2_g2
/
src
/
p_bangou.c
< prev
next >
Wrap
Text File
|
1997-10-13
|
17KB
|
714 lines
/*
post / 郵便番号検索プログラム
p_bangou.c / 番号検索部
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/dos.h>
#include <ctype.h>
#include <mbstring.h>
#include "post.h"
/*
番号検索メイン
*/
void
bangou_kensaku()
{
int len, /* 長さ */
point[B_GEN], /* ofs 格納用 */
uchikiri = 0, /* 打ち切りビット(ないと思うけど) */
nextp = 0, /* 次検索位置 */
kensuu = 0, /* 検索ヒット件数 */
gen_page = 0, /* 現在のページ数 */
zen_page = 0, /* 全ページ数 */
kijun = 0, /* 表示用基準 */
ki = 0, /* 基準から算出した件数 */
aza_sw = 0, /* 字名スイッチ */
s_num = 0, /* 選択用 */
mainlp = 0, /* 表示ループ用 */
lp = 0, /* 表示ループ用(その2) */
lpcnt = 0, /* 表示ループ用(その2) */
shitei_ku_unkn = 0, /* 指定都市内の区名が不明スイッチ(長いねどうも) */
b_ofs = 0, /* 「以下の……」チェック用 */
i1; /* ループ汎用 */
uchar bwork[12], /* 番号ワーク */
ydelim; /* 番号検索用デリミタ */
uchar joukyou[B_GEN], /* ヒット時のオフセット */
ichien[B_GEN]; /* 町村一円スイッチ */
uchar pnum[12][12], /* 郵便番号 */
pknum[12][8], /* 旧番号 */
numwork[12], /* 取りワーク */
numbuff[64], /* 入力用ワーク */
bdelim = '\0'; /* 直前のデリミタ */
uchar page_todou[12][10], /* ページ用の都道府県ワーク */
page_kugun[12][32], /* ページ用の市区郡ワーク */
page_tyouson[12][32], /* ページ用の市内区・町村ワーク */
page_azamei[12][256], /* ページ用の字名ワーク(50文字で打ち切り) */
page_yomi0[12][16], /* ページ用読み(都道府県) */
page_yomi1[12][64], /* ページ用読み(市区郡) */
page_yomi2[12][64], /* ページ用読み(市内区・町村) */
page_yomi3[12][128]; /* ページ用読み(字名) */
struct _inpptr inpp;
len = strlen( input_str );
/* もいっかい検査(1234-567 とかもここに来るので) */
/* なお、ハイフンは3桁目(0から数えて)にしか来ない */
if( !is_bangou_legal( input_str ) ) {
printf("警告 701 : 郵便番号が入力されましたが、");
printf("ハイフン位置がおかしいか、");
printf("不正な記号が入力されています。|%s|\n", input_str );
puts("次のように指定して下さい。");
puts("\t新番号:nnnnnnn, nnn-nnnn");
puts("\t旧番号:nnn, nnnnn, nnn-nn");
return;
}
if( len == 8 && input_str[3] == '-' ) { /* ハイフン付き新番号 nnn-nnnn */
strcpy( bwork, input_str ); /* ワークにコピー */
/* 後ろ4桁を詰める */
for( i1=3; i1<=6; i1++ ) {
input_str[i1] = bwork[i1+1];
}
input_str[7] = '\0';
puts("新番号処理");
ydelim = '*';
} else if( len == 6 && input_str[3] == '-' ) { /* ハイフン付き旧番号 nnn-nn */
strcpy( bwork, input_str );
/* 後ろ2桁を詰める */
input_str[3] = bwork[4];
input_str[4] = bwork[5];
input_str[5] = '\0';
puts("旧番号(5桁)処理");
ydelim = '\'';
} else if( len == 7 ) { /* ハイフンなし新番号 nnnnnnn */
puts("新番号処理");
ydelim = '*';
} else if( len == 5 ) { /* ハイフンなし旧番号 nnnnn */
puts("旧番号(5桁)処理");
ydelim = '\'';
} else if( len == 3 ) { /* 旧番号 nnn */
puts("旧番号(3桁)処理");
ydelim = '\'';
} else {
puts("警告 702 : 郵便番号の桁数が不正です。");
return;
}
/* 番号検索 */
kensuu = 0;
ofs = 0; /* 始めから */
do {
ofs = bm_find( ydelim, input_str, ofs );
if( ofs == -1 ) {
break;
}
if( kensuu == B_GEN ) { /* 件数 == B_GEN で検索打ち切り */
uchikiri = 1;
break;
}
/* ヒットしました */
if( is_not_delim( buf[ofs] ) ) { /* 次位置がデリミタでない */
continue;
}
nextp = ofs; /* 今のオフセットをとっておく */
if( buf[ofs] == '\'' ) { /* 旧番号なら */
ofs++;
pass_next_han(); /* とばす */
}
b_ofs = ofs;
/* 「以下の……」判定 */
if( buf[ofs] == '%' ) { /* 次が字名なら */
/* この番号が何に属しているか調べる */
ofs++;
pass_back_han( '+' );
ofs-= 2;
pass_back_han( '.' ); /* 前はなんだ */
ofs--;
if( buf[ofs] != '%' ) { /* 字名ではない=「以下の……」 */
ofs = nextp; /* オフセットを戻して */
continue; /* とばす */
}
}
ofs = b_ofs;
/* 「以下に掲載が……」がなかった */
point[ kensuu ] = ofs; /* これはデリミタを指している */
kensuu++;
ofs = nextp; /* オフセットを戻す */
} while( 1 );
if( kensuu != 0 ) { /* あった */
gen_page = 1; /* 1ページ目から */
if( kensuu % 12 == 0 ) {
zen_page = kensuu / 12;
} else {
zen_page = kensuu / 12 + 1;
}
if( zen_page == 0 ) {
zen_page = 1;
}
mainlp = 1;
do {
_dos_c_cls_al();
status_print();
printf("該当件数 : %4d 件",kensuu );
if( uchikiri ) { /* 検索を打ち切っていたら */
printf("(打切)");
} else {
printf("\t");
}
printf("\tページ : %2d / %2d\n", gen_page, zen_page);
/* 基準値 */
kijun = (gen_page - 1) * 12;
/* 実際に表示する件数 */
/* 1ページしかない、もしくは最終ページなら調整 */
if( gen_page == zen_page ) {
if( zen_page >= 2 ) {
lpcnt = kensuu - ((zen_page-1)*12);
} else {
lpcnt = kensuu;
}
} else {
lpcnt = 12;
}
/* 初期化 */
for( i1=0; i1<=11; i1++ ) {
page_todou[i1][0] = '\0';
page_kugun[i1][0] = '\0';
page_tyouson[i1][0] = '\0';
page_azamei[i1][0] = '\0';
page_yomi0[i1][0] = '\0';
page_yomi1[i1][0] = '\0';
page_yomi2[i1][0] = '\0';
page_yomi3[i1][0] = '\0';
pnum[i1][0] = '\0';
}
/* データを取ってくる */
for( i1=0; i1<=lpcnt-1; i1++ ) {
ki = kijun + i1;
ofs = point[ ki ];
/* 戻って、直前が字名か町村名かを調べる */
/* 町村名なら一円 */
lp = 1;
ofs-=2;
do {
pass_back_han( '.' );
ofs--;
switch( buf[ofs] ) {
case '%':
bdelim = buf[ofs];
lp = 0;
break;
case ':':
case ';':
ichien[ki] = 1;
bdelim = buf[ofs];
lp = 0;
break;
default:
break;
}
} while( lp );
joukyou[ ki ] = bdelim;
/* 必ず字名から始まるとは限らない */
/* →町村一円のケースもあるので */
ofs++;
aza_sw = 0;
if( bdelim == '%' ) { /* 字名 */
/* 字名を得る */
get_next_han( page_azamei[i1] );
/* 50 字で打ち切り */
// if( strlen( page_azamei[i1] ) >= 48 ) {
// page_azamei[i1][48]='\0';
// strcat( page_azamei[i1], "〈略〉" );
// }
get_next_han2( page_yomi3[i1] ); /* 読み */
ofs++;
get_next_num( numwork );
number_seikei( numwork );
strcpy( pnum[i1], " " );
strcat( pnum[i1], numwork );
ofs++;
get_next_num( pknum[i1] );
aza_sw = 1;
/* 市区郡町村(市内区も)デリミタに */
/* ぶつかるまで、バックトレース */
/* 得られたデリミタは、bdelim へ */
bdelim = backtrace();
}
if( bdelim == '!' ) { /* 市名 */
/* 市名を得る */
get_next_han( page_kugun[i1] );
strcat( page_kugun[i1], "市" );
get_next_han2( page_yomi1[i1] );
if( !aza_sw ) { /* 字名が得られていない */
/* 政令指定都市であれば */
if( seirei_check( page_kugun[i1] ) != -1 ) {
/* 市内区が unknown である */
shitei_ku_unkn = 1;
}
}
/* 県へ戻る準備 */
pass_back_han( ' ' );
bdelim = ' ';
}
if( bdelim == '\"' ) { /* 特別区 */
/* 区名を得る */
get_next_han( page_kugun[i1] );
strcat( page_kugun[i1], "区" );
get_next_han2( page_yomi1[i1] );
/* 特別区は東京都に決まっているのだけど */
pass_back_han( ' ' );
bdelim = ' ';
}
if( bdelim == '$' ) { /* 市内区 */
/* 市内区名を得る */
get_next_han( page_tyouson[i1] );
strcat( page_tyouson[i1], "区" );
get_next_han2( page_yomi2[i1] );
/* 直前の市名を得る */
pass_back_han( '!' );
get_next_han( page_kugun[i1] );
strcat( page_kugun[i1], "市" );
get_next_han2( page_yomi1[i1] );
/* 県へ戻る準備 */
pass_back_han( ' ' );
bdelim = ' ';
}
if( bdelim == ':' ) { /* 町名 */
/* 町名を得る */
get_next_han( page_tyouson[i1] );
strcat( page_tyouson[i1], "町" );
get_next_han2( page_yomi2[i1] );
if( !aza_sw ) {
ichien_check2( ichien[ki],
pnum[i1], pknum[i1] );
}
/* 郡へ戻る準備 */
pass_back_han( '#' );
bdelim = '#';
}
if( bdelim == ';' ) { /* 村名 */
/* 町名を得る */
get_next_han( page_tyouson[i1] );
strcat( page_tyouson[i1], "村" );
get_next_han2( page_yomi2[i1] );
if( !aza_sw ) {
ichien_check2( ichien[ki],
pnum[i1], pknum[i1] );
}
/* 郡へ戻る準備 */
pass_back_han( '#' );
bdelim = '#';
}
if( bdelim == '#' ) { /* 郡名 */
/* 郡名を得る */
get_next_han( page_kugun[i1] );
strcat( page_kugun[i1], "郡" );
get_next_han2( page_yomi1[i1] );
/* 島しょはヌルに */
if( strcmp( page_kugun[i1], "島しょ郡" ) == 0 ) {
strcpy( page_kugun[i1], "" );
strcpy( page_yomi1[i1], "" );
}
/* 県へ戻る準備 */
pass_back_han( ' ' );
bdelim = ' ';
}
if( bdelim == ' ' ) { /* 県名 */
/* 県名を得る */
get_next_han( page_todou[i1] );
get_next_han2( page_yomi0[i1] );
} else {
printf("異常 703 : 番号検索で県名を突破した\n");
printf("point[ki]=|%d|\n",point[ki]);
printf("joukyou[ki]=|%c|\n",joukyou[ki]);
printf("page_todou[i1]=|%s|\n",page_todou[i1]);
printf("page_kugun[i1]=|%s|\n",page_kugun[i1]);
printf("page_tyouson[i1]=|%s|\n",page_tyouson[i1]);
printf("page_azamei[i1]=|%s|\n",page_azamei[i1]);
printf("bdelim=|%c|\n",bdelim);
printf("\n");
return;
}
printf("%4d: ", ki+1 ); /* 件数表示 */
switch( joukyou[ki] ) {
case '%':
printf("字名\t");
break;
case ':':
printf("町名\t");
break;
case ';':
printf("村名\t");
break;
default:
printf("\t\t");
break;
}
/* 桁揃え */
keta( page_todou[i1], page_yomi0[i1] );
keta( page_kugun[i1], page_yomi1[i1] );
keta( page_tyouson[i1], page_yomi2[i1] );
keta( page_azamei[i1], page_yomi3[i1] );
/* 読みの表示 */
printf(" ");
kugiri();
printf("%s",page_yomi0[i1]);
kugiri();
if( page_yomi1[i1][0] != '\0' ) {
printf("%s", page_yomi1[i1] );
kugiri();
}
if( page_yomi2[i1][0] != '\0' ) {
printf("%s", page_yomi2[i1] );
kugiri();
}
if( page_yomi3[i1][0] != '\0' ) {
printf("%s", page_yomi3[i1] );
kugiri();
}
puts("");
/* 次の行 */
//番号は必ず分かっている
// if( pnum[i1][0] != '\0' ) { /* 番号が分かっていれば */
if( k_suppress ) {
printf("\t");
} else {
k_num_disp( pknum[i1] );
}
printf("%s", pnum[i1] ); /* 郵便番号表示 */
// } else {
// printf("\t\t");
// }
kugiri();
/* 地名の表示 */
printf("%s",page_todou[i1]);
kugiri();
if( page_kugun[i1][0] != '\0' ) {
printf("%s",page_kugun[i1]);
kugiri();
}
if( page_tyouson[i1][0] != '\0' ) {
printf("%s",page_tyouson[i1]);
kugiri();
}
if( page_azamei[i1][0] != '\0' ) {
printf("%s",page_azamei[i1]);
kugiri();
}
if( pnum[i1][0] == '*' ) {
printf("(全域)");
}
puts("");
}
/* キー入力 */
puts("");
printf("地名選択:番号");
printf(" 字名切替:a 旧番号切替:k 区切:d 厳密検索:g\n");
if( gen_page != zen_page ) { /* 最終ページなら*/
printf("次ページ:n "); /* 「次ページ」を表示しない */
}
if( gen_page != 1 ) { /* 1ページ目なら */
printf("前ページ:b "); /* 「前ページ」を表示しない */
}
printf("次検索:p 終了:q or e\n");
inpp.max = 64;
inpp.length = 64;
lp = 1;
do{
fep_off();
_dos_gets( &inpp );
strcpy( numbuff, inpp.buffer );
if( numbuff[0] == 'q' || numbuff[0] == 'Q' ||
numbuff[0] == 'e' || numbuff[0] == 'E' ) {
puts("");
exit( 0 );
} else if( numbuff[0] == 'k' || numbuff[0] == 'K' ) {
/* 旧番号モードトグル */
if( k_suppress ) {
k_suppress = 0;
} else {
k_suppress = 1;
}
break;
} else if( numbuff[0] == 'a' || numbuff[0] == 'A' ) {
/* 字名モードトグル */
if( azamei_gentei ) {
azamei_gentei = 0;
} else {
azamei_gentei = 1;
}
break;
} else if( numbuff[0] == 'd' || numbuff[0] == 'D' ) {
/* 区切りモードトグル */
if( kugiri_mode ) {
kugiri_mode = 0;
} else {
kugiri_mode = 1;
}
break;
} else if( numbuff[0] == 'g' || numbuff[0] == 'G' ) {
/* 区切りモードトグル */
if( genmitsu_mode ) {
genmitsu_mode = 0;
} else {
genmitsu_mode = 1;
}
break;
} else if( numbuff[0] == 'n' || numbuff[0] == 'N' ||
numbuff[0] == '\0' ) {
/* 次のページへ */
if( gen_page != zen_page ) {
gen_page++;
break;
}
} else if( numbuff[0] == 'b' || numbuff[0] == 'B' ) {
/* 前のページへ */
if( gen_page != 1 ) {
gen_page--;
break;
}
} else if( numbuff[0] == 'p' || numbuff[0] == 'P' ) {
/* 次検索へ */
dokuji_sw = 1;
return;
}
/* 漢字かカナが入力された? */
if( ismbblead( numbuff[0] ) || /* 1文字はダメよ */
( ismbbkana( numbuff[0] ) && strlen( numbuff ) >= 2 ) ) {
dokuji_sw = 1;
exist_moji = 1;
strcpy( input_str, numbuff );
return;
}
/* 番号が合っているなら終わり */
s_num = atoi( numbuff );
if( s_num >= kijun+1 && s_num <= kijun+lpcnt ) {
mainlp = 0;
break;
}
/* 合っていないなら、郵便番号か? */
if( is_bangou_legal( numbuff ) ) { /* 番号なら */
dokuji_sw = 1;
exist_moji = 1;
strcpy( input_str, numbuff ); /* 番号として検索 */
return;
}
} while ( lp );
} while( mainlp );
/* 選択された */
lpcnt = s_num % 12 - 1; /* ページ中何番が選択されたか? */
if( lpcnt == -1 ) {
lpcnt = 11;
}
puts("");
_dos_c_cls_al();
/* 解析結果の表示 */
printf("\t %s", page_yomi0[lpcnt] ); /* 読みがなの表示 */
if( page_yomi1[lpcnt][0] != '\0' ) {
kugiri();
printf("%s", page_yomi1[lpcnt] );
}
if( page_yomi2[lpcnt][0] != '\0' ) {
kugiri();
printf("%s", page_yomi2[lpcnt] );
}
kugiri();
printf("\n");
printf("解析結果 : %s", page_todou[lpcnt] );
kugiri();
if( page_kugun[lpcnt][0] != '\0' ) {
printf("%s", page_kugun[lpcnt] );
kugiri();
}
if( page_tyouson[lpcnt][0] != '\0' ) {
printf("%s", page_tyouson[lpcnt] );
kugiri();
}
printf("\n\n");
/* 1件しかないね? */
if( pnum[lpcnt][0] == '*' ) {
printf("%s%s", page_todou[lpcnt], page_kugun[lpcnt] );
if( page_tyouson[lpcnt][0] != '\0' ) {
moji_pr( page_tyouson[lpcnt], input_str );
}
printf("内の郵便番号はすべて %s ", &pnum[lpcnt][1] );
if( !k_suppress ) {
k_num_disp( pknum[lpcnt] );
}
printf(" です。\n");
} else {
if( !k_suppress ) {
k_num_disp( pknum[lpcnt] );
}
printf("%s", &pnum[lpcnt][1] ); /* 頭は表示しない */
printf(": ");
moji_pr( page_azamei[lpcnt], input_str );
printf("(%s)\n", page_yomi3[lpcnt] );
}
dokuji_sw = 1;
} else { /* kensuu は 0 、つまりヒットしなかった */
puts("警告 704 : 入力された郵便番号は見つかりませんでした。");
}
return;
}
/*
一円チェック(その2)
町村内がすべて同一郵便番号の場合、pnum に書き込む
「以下に掲載が……」の場合、1 を返す
*/
void
ichien_check2( int ichien, uchar *pnum, uchar *knum )
{
uchar numwork[8]; /* 郵便番号ワーク */
ofs++;
get_next_num( numwork );
number_seikei( numwork );
ofs++;
get_next_num( knum );
if( buf[ofs] != '%' ) { /* 字名がない */
if( ichien ) {
strcpy( pnum, "*" );
strcat( pnum, numwork ); /* 一円である */
} else {
return;
}
}
return;
}
/*
郵便番号検査
フォーマットがおかしければ、0を返す
*/
int
is_bangou_legal( uchar *bangou )
{
int len, /* bangou 長さ */
i1; /* ループ汎用 */
len = strlen( bangou );
/* 長さが違うなら、違う */
if( len != 3 && len != 5 && len != 6 && len != 7 && len != 8 ) {
return 0;
}
/* ハイフン位置は正しいか? */
for( i1=0; i1<=len-1; i1++ ) {
if( (len == 6 && (i1 == 3 && bangou[i1] == '-')) ||
(len == 8 && (i1 == 3 && bangou[i1] == '-')) ) {
continue; /* ハイフンはとばす */
}
if( !isdigit( bangou[i1] ) ) { /* 数字でないなら */
return 0; /* イリーガル */
}
}
return 1; /* 生き残ったらリーガル */
}